﻿using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Collections.Generic;

namespace KeyPressAnimation
{
    public partial class MainWindow : Window
    {
        private bool isDragging = false;
        private Point startPoint;
        private LowLevelKeyboardHook _keyboardHook;
        private Canvas _animationCanvas;

        public MainWindow()
        {
            InitializeComponent();

            // 创建用于动画的Canvas
            _animationCanvas = new Canvas();
            MainContainer.Children.Add(_animationCanvas);

            // 设置窗口位置
            this.Left = SystemParameters.WorkArea.Width - this.Width - 100;
            this.Top = SystemParameters.WorkArea.Height - this.Height - 100;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // 安装全局键盘钩子
            _keyboardHook = new LowLevelKeyboardHook();
            _keyboardHook.OnKeyPressed += KeyboardHook_OnKeyPressed;
            _keyboardHook.HookKeyboard();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            // 卸载键盘钩子
            _keyboardHook.UnHookKeyboard();
        }

        private void KeyboardHook_OnKeyPressed(object sender, KeyPressedArgs e)
        {
            // 在UI线程上执行
            Dispatcher.Invoke(() =>
            {
                // 将Key转换为字符
                string keyString = GetCharFromKey(e.Key);

                if (!string.IsNullOrEmpty(keyString))
                {
                    CreateKeyAnimation(keyString);
                }
            });
        }

        private string GetCharFromKey(Key key)
        {
            // 过滤功能键
            if (key >= Key.LeftShift && key <= Key.RightAlt ||
                key == Key.CapsLock || key == Key.Escape ||
                key == Key.Enter || key == Key.Tab ||
                key == Key.Back || key == Key.Delete)
                return null;

            // 将Key转换为字符
            char? character = KeyToChar(key);
            return character?.ToString() ?? key.ToString();
        }

        private char? KeyToChar(Key key)
        {
            // 处理数字键
            if (key >= Key.D0 && key <= Key.D9)
                return (char)('0' + (key - Key.D0));

            // 处理字母键
            if (key >= Key.A && key <= Key.Z)
                return (char)('A' + (key - Key.A));

            // 处理小键盘数字
            if (key >= Key.NumPad0 && key <= Key.NumPad9)
                return (char)('0' + (key - Key.NumPad0));

            return null;
        }

        private void CreateKeyAnimation(string keyText)
        {
            // 创建文本块显示按键
            var textBlock = new TextBlock
            {
                Text = keyText,
                FontSize = GetRandomFontSize(),
                Foreground = GetRandomColorBrush(),
                FontWeight = FontWeights.Bold,
                Opacity = 0.9
            };

            // 随机位置（底部）
            double startX = new Random().Next(0, (int)(Width));
            double startY = Height;

            Canvas.SetLeft(textBlock, startX);
            Canvas.SetTop(textBlock, startY);
            _animationCanvas.Children.Add(textBlock);

            // 创建动画
            var animation = new DoubleAnimation
            {
                From = startY,
                To = -100, // 上升到窗口外
                Duration = TimeSpan.FromSeconds(GetRandomDuration()),
                FillBehavior = FillBehavior.Stop
            };

            // 透明度动画
            var opacityAnimation = new DoubleAnimation
            {
                From = 0.9,
                To = 0,
                Duration = TimeSpan.FromSeconds(GetRandomDuration() * 0.8),
                FillBehavior = FillBehavior.Stop
            };

            // 动画完成时移除元素
            animation.Completed += (s, e) =>
            {
                _animationCanvas.Children.Remove(textBlock);
            };

            // 开始动画
            textBlock.BeginAnimation(Canvas.TopProperty, animation);
            textBlock.BeginAnimation(UIElement.OpacityProperty, opacityAnimation);
        }

        private double GetRandomDuration()
        {
            return new Random().NextDouble() * 2 + 3; // 3-5秒
        }

        private double GetRandomFontSize()
        {
            return new Random().Next(24, 72);
        }

        private Brush GetRandomColorBrush()
        {
            var colors = new[]
            {
                Brushes.LightSkyBlue,
                Brushes.LightGreen,
                Brushes.LightPink,
                Brushes.LightYellow,
                Brushes.LightCoral,
                Brushes.LightSeaGreen,
                Brushes.LightSteelBlue,
                Brushes.Plum,
                Brushes.Aquamarine,
                Brushes.Gold
            };

            return colors[new Random().Next(colors.Length)];
        }

        // 拖拽相关代码
        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            isDragging = true;
            startPoint = e.GetPosition(this);
            this.CaptureMouse();
        }

        private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            isDragging = false;
            this.ReleaseMouseCapture();
        }

        private void Window_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging && e.LeftButton == MouseButtonState.Pressed)
            {
                Point currentPoint = e.GetPosition(this);
                Vector delta = currentPoint - startPoint;

                this.Left += delta.X;
                this.Top += delta.Y;
            }
        }

        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }

    // 键盘钩子相关类
    public class KeyPressedArgs : EventArgs
    {
        public Key Key { get; private set; }

        public KeyPressedArgs(Key key)
        {
            Key = key;
        }
    }

    public class LowLevelKeyboardHook
    {
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;

        private LowLevelKeyboardProc _proc;
        private IntPtr _hookID = IntPtr.Zero;

        public event EventHandler<KeyPressedArgs> OnKeyPressed;

        public LowLevelKeyboardHook()
        {
            _proc = HookCallback;
        }

        public void HookKeyboard()
        {
            _hookID = SetHook(_proc);
        }

        public void UnHookKeyboard()
        {
            UnhookWindowsHookEx(_hookID);
        }

        private IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (var curProcess = System.Diagnostics.Process.GetCurrentProcess())
            using (var curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                var key = KeyInterop.KeyFromVirtualKey(vkCode);

                OnKeyPressed?.Invoke(this, new KeyPressedArgs(key));
            }

            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
    }
}